package com.boe.csb.core.common.utils;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.Type;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class GsonUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(GsonUtils.class);
    private static final Gson gson = new GsonBuilder().setPrettyPrinting().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
    private static final Gson longDateGson = new GsonBuilder()
            .registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {

                public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                        throws JsonParseException {
                    return new Date(json.getAsJsonPrimitive().getAsLong());
                }
            }).setDateFormat(DateFormat.LONG).create();
    
    private static final Gson longDoubleGson = new GsonBuilder()
        .registerTypeAdapter(
            new TypeToken<Map<String, Object>>(){}.getType(), 
            new JsonDeserializer<Map<String, Object>>() {
            @Override
            public Map<String, Object> deserialize(
            JsonElement json, Type typeOfT, 
            JsonDeserializationContext context) throws JsonParseException {

                Map<String, Object> treeMap = new HashMap<>();
                JsonObject jsonObject = json.getAsJsonObject();
                Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
                for (Map.Entry<String, JsonElement> entry : entrySet) {
                    treeMap.put(entry.getKey(), entry.getValue());
                }
                return treeMap;
            }
        }).create();

    public static JsonObject string2JsonObject(String jsonStr) {
        return gson.fromJson(jsonStr, JsonElement.class).getAsJsonObject();
    }

    public static String object2String(Object object) {
        return gson.toJson(object);
    }

    public static String object2LongDateString(Object object) {
        return longDateGson.toJson(object);
    }
    

    /**
     * 获取 new TypeToken<Collection<Integer>>(){}.getType();
     **/
    public static <T> T string2Object(String jsonString, Type type) {
        try {
            return gson.fromJson(jsonString, type);
        } catch (JsonSyntaxException e) {
            LOGGER.warn("Gson string to object error, string : {} to object type {}", jsonString, type);
            throw e;
        }
    }
    
    /**
     * 获取 new TypeToken<Collection<Integer>>(){}.getType();
     **/
    public static <T> T longDoubleString2Object(String jsonString) {
        try {
            return longDoubleGson.fromJson(jsonString, new TypeToken<Map<String, Object>>(){}.getType());
        } catch (JsonSyntaxException e) {
            LOGGER.warn("Gson string to object error, string : {}", jsonString);
            throw e;
        }
    }

    /**
     * 获取 new TypeToken<Collection<Integer>>(){}.getType();
     **/
    public static <T> T longDateString2Object(String jsonString, Type type) {
        try {
            return longDateGson.fromJson(jsonString, type);
        } catch (JsonSyntaxException e) {
            LOGGER.warn("Gson string to object error, string : {} to object type {}", jsonString, type);
            throw e;
        }
    }
    
}
